package com.scrm.server.wx.cp.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.scrm.api.wx.cp.dto.WxFissionStageQueryDTO;
import com.scrm.api.wx.cp.dto.WxFissionStageSaveDTO;
import com.scrm.api.wx.cp.entity.WxFissionStage;
import com.scrm.api.wx.cp.vo.WxFissionStageVO;
import com.scrm.common.constant.Constants;
import com.scrm.common.exception.BaseException;
import com.scrm.common.util.ListUtils;
import com.scrm.common.util.UUID;
import com.scrm.server.wx.cp.mapper.WxFissionStageMapper;
import com.scrm.server.wx.cp.service.*;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.cp.bean.external.WxCpContactWayResult;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 企微应用宝-阶梯任务信息表 服务实现类
 * @author xxh
 * @since 2022-03-21
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class WxFissionStageServiceImpl extends ServiceImpl<WxFissionStageMapper, WxFissionStage> implements IWxFissionStageService {

    @Autowired
    private IContactWayService contactWayService;

    @Autowired
    private IWxContactExpirationService contactExpirationService;

    @Autowired
    private IWxTagService tagService;

    @Autowired
    private IStaffService staffService;

    @Override
    public List<WxFissionStageVO> queryList(WxFissionStageQueryDTO dto){
        LambdaQueryWrapper<WxFissionStage> wrapper = new QueryWrapper<WxFissionStage>()
        .lambda().eq(WxFissionStage::getExtCorpId, dto.getExtCorpId())
                .eq(WxFissionStage::getTaskId, dto.getTaskId())
                .orderByAsc(WxFissionStage::getNum);
        return Optional.ofNullable(list(wrapper)).orElse(new ArrayList<>()).stream().map(this::translation).collect(Collectors.toList());
    }

    /**
     * 翻译
     * @param wxFissionStage 实体
     * @return WxFissionStageVO 结果集
     * @author xxh
     * @date 2022-03-21
     */
    private WxFissionStageVO translation(WxFissionStage wxFissionStage){
        WxFissionStageVO vo = new WxFissionStageVO();
        BeanUtils.copyProperties(wxFissionStage, vo);

        if (ListUtils.isNotEmpty(vo.getTags())) {
            vo.setTagList(tagService.listByIds(vo.getTags()));
        }
        if (ListUtils.isNotEmpty(vo.getExtStaffIds())) {
            vo.setStaffVOList(staffService.listByExtIds(vo.getExtCorpId(), vo.getExtStaffIds()));
        }
        return vo;
    }


    @Override
    public WxFissionStage checkExists(String id){
        if (StringUtils.isBlank(id)) {
            return null;
        }
        WxFissionStage byId = getById(id);
        if (byId == null) {
            throw new BaseException("企微应用宝-阶梯任务信息表不存在");
        }
        return byId;
    }

    @Override
    public List<WxFissionStage> buildFissionStage(String taskId, String extCorpId, Date expireTime, List<WxFissionStageSaveDTO> stageSaveDTOS) {

        return stageSaveDTOS.stream().map(e -> {

            String id = UUID.get16UUID();

            //生成渠道活码
            String state = Constants.FISSION_SERVICE_CONTACT_WAY_STATE_PRE + id;
            WxCpContactWayResult contact = contactWayService.getCommonContact(extCorpId, null, state, e.getExtStaffIds(), true);

            //设置活码过期时间
            contactExpirationService.saveOrUpdate(extCorpId, contact.getConfigId(), taskId, expireTime);

            //构造参数
            WxFissionStage res = new WxFissionStage();
            BeanUtils.copyProperties(e, res);

            return res.setId(id).setTaskId(taskId).setExtCorpId(extCorpId)
                    .setConfigId(contact.getConfigId()).setState(state).setQrCode(contact.getQrCode())
                    .setCreatedAt(new Date()).setUpdatedAt(new Date());
        }).collect(Collectors.toList());

    }

    @Override
    public void updateFissionStage(String taskId, String extCorpId, Date expireTime, List<WxFissionStageSaveDTO> stageSaveDTOS) {

        //查出全部旧的
        LambdaQueryWrapper<WxFissionStage> queryWrapper = new QueryWrapper<WxFissionStage>().lambda()
                .eq(WxFissionStage::getExtCorpId, extCorpId)
                .eq(WxFissionStage::getTaskId, taskId);

        List<WxFissionStage> oldList = list(queryWrapper);

        List<String> idList = new ArrayList<>(oldList.size());
        List<String> configIdList = new ArrayList<>(oldList.size());

        oldList.forEach(e -> {
            idList.add(e.getId());
            configIdList.add(e.getConfigId());
        });

        //先删渠道活码
        contactWayService.deleteByConfigIds(extCorpId, configIdList);

        //再删数据
        removeByIds(idList);

        //新增回来
        List<WxFissionStage> fissionStage = buildFissionStage(taskId, extCorpId, expireTime, stageSaveDTOS);

        saveBatch(fissionStage);
    }

    @Override
    public Map<Integer, Integer> getStageNumMap(String extCorpId, String taskId) {
        List<WxFissionStage> stageList = list(new QueryWrapper<WxFissionStage>().lambda()
                .eq(WxFissionStage::getExtCorpId, extCorpId)
                .eq(WxFissionStage::getTaskId, taskId));

        return stageList.stream().collect(Collectors.toMap(WxFissionStage::getStage, WxFissionStage::getNum));
    }
}
